﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using NLBS.Entity;
using NLBS.Data;
using System.Xml;
using NLBS.Framework;

namespace NLBS.Syndication
{
    /// <summary>
    /// Base class for writing RSS and ATOM feeds.
    /// </summary>
    public abstract class BaseSyndicationWriter<T> : XmlTextWriter
    {
        private StringWriter writer = null;
        protected Dictionary<string,Setting> info;
        DateTime dateLastViewedFeedItemPublished = NullValue.NullDateTime;
        protected DateTime latestPublishDate = NullValue.NullDateTime;
        protected bool useDeltaEncoding = false;
        protected bool clientHasAllFeedItems = false;
        protected BlogInfo blogInfo;
        #region 构造函数

        /// <summary>
        /// Creates a new <see cref="BaseSyndicationWriter"/> instance.
        /// </summary>
        /// <param name="sw">Sw.</param>
        protected BaseSyndicationWriter(StringWriter sw)
            : this(sw, NullValue.NullDateTime, false)
        {
        }

        /// <summary>
        /// Creates a new <see cref="BaseSyndicationWriter"/> instance.
        /// </summary>
        /// <param name="dateLastViewedFeedItemPublished"></param>
        protected BaseSyndicationWriter(DateTime dateLastViewedFeedItemPublished, bool useDeltaEncoding)
            : this(new StringWriter(), dateLastViewedFeedItemPublished, useDeltaEncoding)
        {
        }

        /// <summary>
        /// Creates a new <see cref="BaseSyndicationWriter"/> instance.
        /// </summary>
        /// <param name="sw">Sw.</param>
        /// <param name="dateLastViewedFeedItemPublished">Last viewed feed item.</param>
        protected BaseSyndicationWriter(StringWriter sw, DateTime dateLastViewedFeedItemPublished, bool useDeltaEncoding)
            : base(sw)
        {
            this.dateLastViewedFeedItemPublished = dateLastViewedFeedItemPublished;
            writer = sw;
            info = DbProvider.Instance().GetSettings();
            blogInfo = BlogInfo.Instance();
            this.useDeltaEncoding = useDeltaEncoding;
            this.Formatting = System.Xml.Formatting.Indented;
            this.Indentation = 4;
        }

        #endregion

        /// <summary>
        /// Gets the string writer.
        /// </summary>
        /// <value></value>
        public StringWriter StringWriter
        {
            get
            {
                Build();
                return writer;
            }
        }

        /// <summary>
        /// Gets the XML.
        /// </summary>
        /// <value></value>
        public string Xml
        {
            get
            {
                return this.StringWriter.ToString();
            }
        }

        /// <summary>
        /// Returns the XML
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return Xml;
        }

        /// <summary>
        /// Gets a value indicating whether the feed client has all the feed items.
        /// </summary>
        /// <value>
        /// 	<c>true</c> if the client has all feed items; otherwise, <c>false</c>.
        /// </value>
        public bool ClientHasAllFeedItems
        {
            get
            {
                return clientHasAllFeedItems;
            }
        }

        /// <summary>
        /// Gets the publish date of the latest syndicated item.
        /// </summary>
        /// <value></value>
        public DateTime LatestPublishDate
        {
            get
            {
                return latestPublishDate;
            }
        }

        /// <summary>
        /// Gets the publish date of the last syndicated feed item 
        /// that the client aggregator viewed.  This is sent as 
        /// the ETag.
        /// </summary>
        /// <value></value>
        public DateTime DateLastViewedFeedItemPublished
        {
            get { return this.dateLastViewedFeedItemPublished; }
        }

        private bool _useAggBugs = false;
        public bool UseAggBugs
        {
            get { return this._useAggBugs; }
            set { this._useAggBugs = value; }
        }

        private bool _allowComments = true;
        public bool AllowComments
        {
            get { return this._allowComments; }
            set { this._allowComments = value; }
        }

        /// <summary>
        /// Gets or sets the entries to be rendered in the feed.
        /// </summary>
        /// <value>The entries.</value>
        public IList<T> Items
        {
            get { return this.items; }
            set { this.items = value; }
        }
        private IList<T> items;

        /// <summary>
        /// Builds the feed.
        /// </summary>
        protected abstract void Build();

        /// <summary>
        /// Builds the feed with delta-encoding possible.
        /// </summary>
        /// <param name="dateLastViewedFeedItemPublished">The date last viewed feed item published.</param>
        protected abstract void Build(DateTime dateLastViewedFeedItemPublished);
    }
}
